﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Input;
using VMDS.Business.Entities;
using VMDS.GUIClient.Helper;
using VMDS.GUIClient.Model;

namespace VMDS.GUIClient.ViewModels.Management.Tasks
{
    
    class TaskManagementViewModel:BaseViewModel
    {
        private string _pcf;
        public string PcFilter
        {
            get { return _pcf; }
            set
            {
                _pcf = value;
                pcfilter(value);
            }
        }
        private string _vmf;
        public string VmFilter
        {
            get { return _vmf; }
            set
            {
                _vmf = value;
                vmfilter(value);
            }
        }

        void pcfilter(string f)
        {
           FilteredPCs= new ObservableCollection<ClientPC>(PCs.Where(pc => pc.Name.ToLower().Contains(f.ToLower())));
        }

        void vmfilter(string f)
        {
            FilteredVMs=new ObservableCollection<VM>(VMs.Where(vm => vm.Name.ToLower().Contains(f.ToLower())));
        }

        private ObservableCollection<ClientPC> _fpcs;
        public ObservableCollection<ClientPC> FilteredPCs
        {
            get { return _fpcs; }
            set { _fpcs = value;OnPropertyChanged(()=>FilteredPCs); }
        }

        private ObservableCollection<VM> _fvms;
        public ObservableCollection<VM> FilteredVMs
        {
            get { return _fvms; }
            set { _fvms = value;OnPropertyChanged(()=>FilteredVMs); }
        }

        private ObservableCollection<ClientPC> _pcs;
        public ObservableCollection<ClientPC> PCs
        {
            get { return _pcs; }
            set { _pcs = value;OnPropertyChanged(()=>PCs); }
        }

        private ObservableCollection<ClientPC> _selPcs;
        public ObservableCollection<ClientPC> SelectedPCs
        { 
            get { return _selPcs; }
            set { _selPcs = value;OnPropertyChanged(()=>SelectedPCs); }
        }

        private ObservableCollection<string> _cl;
        public ObservableCollection<string> CompletedLog
        {
            get { return _cl; }
            set { _cl = value;OnPropertyChanged(()=>CompletedLog); }
        }

        void FillVms()
        {
            ManagerDataStore.Instance.LoadData();
            FilteredVMs=new ObservableCollection<VM>();
            var tasks = ManagerDataStore.Instance.Tasks.Where(x => (x.ClientPCId == SelectedPC.Id));
            CompletedLog.Clear();
            var v = ManagerDataStore.Instance.VMs;
            var completedTasks = tasks.Where(x => x.Completed);
            foreach (var vm in completedTasks.Select(task => v.SingleOrDefault(x => x.Id == task.VMId)).Where(vm => (vm != null)))
            {
                CompletedLog.Add(vm.Name+" установлена");
            }
            

            var t = tasks.Where(x=>!x.Completed);
            
            foreach (var vm in t.Select(task => v.SingleOrDefault(x => x.Id == task.VMId)))
            {
                FilteredVMs.Add(vm);
            }
        }

        private ClientPC _spc;
        public ClientPC SelectedPC
        {
            get { return _spc; }
            set { _spc = value;SelectTask();FillVms(); }
        }

        private VM _svm;
        public VM SelectedVM
        {
            get { return _svm; }
            set { _svm = value;SelectTask(); }
        }

        private int _p;
        public int CurrentProgress
        {
            get { return _p; }
            set { _p = value;OnPropertyChanged(()=>CurrentProgress); }
        }

        private string _user;
        public string CurrentUser
        {
            get { return _user; }
            set { _user = value;OnPropertyChanged(()=>CurrentUser); }
        }

        private string _curOp;
        public string CurrentOperation
        {
            get { return _curOp; }
            set { _curOp = value;OnPropertyChanged(()=>CurrentOperation); }
        }

        private string _expdate;
        public string CurrentExpDate
        {
            get { return _expdate; }
            set { _expdate = value;OnPropertyChanged(()=>CurrentExpDate); }
        }

        private string _speed;
        public string CurrentSpeed
        {
            get { return _speed; }
            set { _speed = value;OnPropertyChanged(()=>CurrentSpeed); }
        }

        private Task CurrentTask;

        void SelectTask()
        {
            Task t=null;
            if ((SelectedVM != null) && (SelectedPC != null))
            {

                t =
                    ManagerDataStore.Instance.Tasks.SingleOrDefault(
                        x => (x.VMId == SelectedVM.Id) && (x.ClientPCId == SelectedPC.Id) && (!x.Completed));
            }
            CurrentTask = t;
            OnPropertyChanged(() => StopTask);
                
            if (t != null)
            {
                CurrentExpDate = t.ExpDate.Value.ToString();
                CurrentUser = t.CreatedBy;
                CurrentOperation = t.State.ToString();
            }
            else
            {
                CurrentExpDate = "";
                CurrentUser = "";
                CurrentOperation = "";
            }
        }
        void stop()
        {
            ServiceLocator.MainService.DeleteTask(CurrentTask);
            ManagerDataStore.Instance.LoadData();
            FilteredPCs = ManagerDataStore.Instance.ClientPCs;
            SelectTask();
            ShowMessageBox("Задание остановлено");

        }

        public ICommand StopTask
        {
            get { return new BaseCommand(stop,()=> CurrentTask != null); }
        }

        private ObservableCollection<VM> _vms;
        public ObservableCollection<VM> VMs
        {
            get { return _vms; }
            set { _vms = value;OnPropertyChanged(()=>VMs); }
        }

        private ObservableCollection<VM> _svms;
        public ObservableCollection<VM> SelectedVMs
        {
            get { return _svms; }
            set { _svms = value;OnPropertyChanged(()=>SelectedVMs); }
        }
    
        public TaskManagementViewModel()
        {
            SelectedPCs = new ObservableCollection<ClientPC>();
            SelectedPCs.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(CollectionChanged);
            SelectedVMs = new ObservableCollection<VM>();
            SelectedVMs.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(CollectionChanged);
            PCs = ManagerDataStore.Instance.ClientPCs;
            VMs = ManagerDataStore.Instance.VMs;
            FilteredPCs = PCs;
            CompletedLog=new ObservableCollection<string>();
        }

        bool AlreadyAssigned()
        {
            
            foreach (var pc in SelectedPCs)
            {
                var tasks = ManagerDataStore.Instance.Tasks.Where(x => (x.ClientPCId == pc.Id)&&(!x.Completed));
                foreach (var vm in SelectedVMs.Where(vm => tasks.Any(t => t.VMId == vm.Id)))
                {
                    ShowMessageBox("Компьютеру "+pc.Name+" уже назначена установка "+vm.Name);
                    return true;
                }
            }
            return false;
        }
        bool CanAdd()
        {
            var c1 = SelectedPCs.Count > 0;
            var c2 = SelectedVMs.Count > 0;
            var c3 = (ExpDate >= DateTime.Now);
            var c4 = !AlreadyAssigned();
            return c1 && c2 && c3 && c4;
        }

        private void add()
        {
            
            List<Task> tasks= (from pc in SelectedPCs
                               from vm in SelectedVMs
                               select new Task()
                                          {
                                              ClientPCId = pc.Id, VMId = vm.Id,
                                              CreatedBy = Environment.UserName,ExpDate = ExpDate
                                          }).ToList();
            ServiceLocator.MainService.AddTasks(tasks.ToArray());
            PCs=new ObservableCollection<ClientPC>();
            VMs=new ObservableCollection<VM>();
            ManagerDataStore.Instance.LoadData();
            PCs = ManagerDataStore.Instance.ClientPCs;
            VMs = ManagerDataStore.Instance.VMs;
            
            ShowMessageBox("Задание добавлено");
        }
        public ICommand Add
        {
            get { return new BaseCommand(add, CanAdd); }
        }

        public DateTime MinDate
        {
            get { return DateTime.Now; }
        }

        private DateTime _d;
        public DateTime ExpDate
        {
            get { return _d; }
            set { _d = value;OnPropertyChanged(()=>Add); }
        }

        void CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            OnPropertyChanged(()=>Add);
        }

    }
}
